{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "fd89d8a1-34f4-4c33-986b-7c5b1c2917c0",
   "metadata": {},
   "outputs": [],
   "source": [
    "import pandas as pd  # 导入数据处理库 Pandas\n",
    "import numpy as np  # 导入数值计算库 NumPy\n",
    "from sklearn.model_selection import train_test_split\n",
    "from sklearn.ensemble import RandomForestRegressor\n",
    "from sklearn.metrics import mean_squared_log_error\n",
    "import matplotlib.pyplot as plt # 导入 matplotlib 中的 plt 函数"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "1e84f66c-72f3-43b9-8611-832a6e0bde84",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "                    role_id  create_time  day\n",
      "0  28b9114a5784b724997257c3   1593268403    2\n",
      "1  51d43143f0e8c695792ee1d4   1613439868    2\n",
      "2  52f2bb2665cdb5d81dd245ba   1612927043    2\n"
     ]
    }
   ],
   "source": [
    "# 读取玩家角色表数据\n",
    "roles = pd.read_csv(r'D:\\作业\\机器学习\\CCF BDCI\\role_id.csv')\n",
    "# 创建一个空列表用于存放不同天数的角色数据\n",
    "dfs = []\n",
    "# 针对七天的数据进行循环\n",
    "for i in range(2, 9):\n",
    "    # 复制角色表数据至临时变量 tmp\n",
    "    tmp = roles.copy()\n",
    "    # 在临时变量中添加一个名为 'day' 的列，并赋值为当前的天数 i\n",
    "    tmp['day'] = i\n",
    "    # 将处理后的临时数据添加至列表 dfs 中\n",
    "    dfs.append(tmp)\n",
    "# 将所有临时数据拼接成一个完整的数据集，并重新设置索引\n",
    "data = pd.concat(dfs).reset_index(drop=True)\n",
    "# 打印data前三行数据的代码\n",
    "print(data.head(3))\n",
    "\n",
    "##以上代码主要是读取玩家角色表数据，并通过循环创建了一个包含七天数据的 data 数据集。\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "6e8d67af-c111-4d27-9663-429d6ff4b476",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "                    role_id  use_t4  use_t1  use_t2  use_t3  remain_t1  \\\n",
      "0  f1e7b2e5fef72472978855c8       0     -50       0       0       1124   \n",
      "1  f1e7b2e5fef72472978855c8       0      -1       0       0       1176   \n",
      "2  f1e7b2e5fef72472978855c8       0      -1       0       0       1179   \n",
      "\n",
      "   remain_t2       mtime  remain_t4  day  \n",
      "0         60  1614614402          0    2  \n",
      "1         60  1614614404          0    2  \n",
      "2         60  1614614404          0    2  \n"
     ]
    }
   ],
   "source": [
    "# 读取货币消耗表数据\n",
    "consume = pd.read_csv(r'D:\\作业\\机器学习\\CCF BDCI\\role_consume_op.csv')\n",
    "# 将 'dt' 列转换为 Pandas 的日期时间格式\n",
    "consume['dt'] = pd.to_datetime(consume['dt'])\n",
    "# 从日期时间中提取天数，并创建一个名为 'day' 的新列\n",
    "consume['day'] = consume['dt'].dt.day\n",
    "# 删除 \"dt\" 列，并将结果赋值回 consume\n",
    "consume = consume.drop('dt', axis=1)\n",
    "# 删除 \"level\" 列，并将结果赋值回 consume，因为我主观上认为level和充值金额间没显著联系\n",
    "consume = consume.drop('level', axis=1)\n",
    "\"以上代码主要读取了货币消耗表的数据，并对日期时间进行了处理，提取了每条记录对应的日期中的天数，并将结果保存在新创建的 'day' 列中。\"\n",
    "print(consume.head(3))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "1386100e-29d8-4feb-b4c6-9e8dfedc59ad",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "                    role_id  create_time  day  use_t1_count  use_t1_sum  \\\n",
      "0  28b9114a5784b724997257c3   1593268403    2           1.0      -398.0   \n",
      "1  51d43143f0e8c695792ee1d4   1613439868    2          31.0       135.0   \n",
      "2  52f2bb2665cdb5d81dd245ba   1612927043    2           5.0     -1464.0   \n",
      "3  1f3c325b343a3f56b898265e   1614044315    2          12.0       -20.0   \n",
      "4  76d3a7bd0a8ed2b011a99aae   1614056679    2           5.0      -140.0   \n",
      "\n",
      "   use_t2_count  use_t2_sum  use_t3_count  use_t3_sum  use_t4_count  \\\n",
      "0           1.0         0.0           1.0         0.0           1.0   \n",
      "1          31.0         0.0          31.0         0.0          31.0   \n",
      "2           5.0         0.0           5.0         0.0           5.0   \n",
      "3          12.0         0.0          12.0         0.0          12.0   \n",
      "4           5.0         0.0           5.0         0.0           5.0   \n",
      "\n",
      "   use_t4_sum  \n",
      "0         0.0  \n",
      "1         0.0  \n",
      "2         0.0  \n",
      "3         0.0  \n",
      "4         0.0  \n"
     ]
    }
   ],
   "source": [
    "# 对货币消耗表进行处理并合并到 data 数据中\n",
    "for i in range(1, 5):  # 针对特定范围内的数据列进行循环处理\n",
    "    for m in ['count', 'sum']:  # 针对 'use_t{i}' 列的计数和求和进行循环处理\n",
    "        # 根据 'role_id' 和 'day' 分组计算 'use_t{i}' 列的聚合统计，并重新设置列名\n",
    "        tmp = consume.groupby(['role_id', 'day'])[f'use_t{i}'].agg(m).to_frame(name=f'use_t{i}_{m}').reset_index()\n",
    "        # 将新计算的数据根据 'role_id' 和 'day' 合并到原始 data 数据中\n",
    "        data = data.merge(tmp, on=['role_id', 'day'], how='left')\n",
    "\n",
    "\n",
    "# 检查合并后数据表的数据\n",
    "print(data.head())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "7d16c981-19ae-43e9-b382-6ad525a26d28",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "                    role_id  create_time  day  use_t1_count  use_t1_sum  \\\n",
      "0  28b9114a5784b724997257c3   1593268403    2           1.0      -398.0   \n",
      "1  51d43143f0e8c695792ee1d4   1613439868    2          31.0       135.0   \n",
      "2  52f2bb2665cdb5d81dd245ba   1612927043    2           5.0     -1464.0   \n",
      "3  1f3c325b343a3f56b898265e   1614044315    2          12.0       -20.0   \n",
      "4  76d3a7bd0a8ed2b011a99aae   1614056679    2           5.0      -140.0   \n",
      "\n",
      "   use_t2_count  use_t2_sum  use_t3_count  use_t3_sum  use_t4_count  \\\n",
      "0           1.0         0.0           1.0         0.0           1.0   \n",
      "1          31.0         0.0          31.0         0.0          31.0   \n",
      "2           5.0         0.0           5.0         0.0           5.0   \n",
      "3          12.0         0.0          12.0         0.0          12.0   \n",
      "4           5.0         0.0           5.0         0.0           5.0   \n",
      "\n",
      "   use_t4_sum  upgrade_type_counts  item_usage_counts  total_levels_upgraded  \\\n",
      "0         0.0                  NaN                NaN                    NaN   \n",
      "1         0.0                 49.0               49.0                    6.0   \n",
      "2         0.0                  5.0                5.0                    4.0   \n",
      "3         0.0                 40.0               40.0                   15.0   \n",
      "4         0.0                  NaN                NaN                    NaN   \n",
      "\n",
      "   average_levels_upgraded  total_items_used  average_items_used  \n",
      "0                      NaN               NaN                 NaN  \n",
      "1                 0.122449              49.0                 1.0  \n",
      "2                 0.800000               5.0                 1.0  \n",
      "3                 0.375000              40.0                 1.0  \n",
      "4                      NaN               NaN                 NaN  \n"
     ]
    }
   ],
   "source": [
    "# 读取角色进化表数据并处理\n",
    "evolve = pd.read_csv(r'D:\\作业\\机器学习\\CCF BDCI\\role_evolve_op.csv')\n",
    "evolve['dt'] = pd.to_datetime(evolve['dt'])  # 将日期列转换为 Pandas 的日期时间格式\n",
    "evolve['day'] = evolve['dt'].dt.day  # 提取日期中的天数，并创建 'day' 列\n",
    "\n",
    "# 计算角色升级差值和重命名列名\n",
    "evolve['n_level_up'] = evolve['new_lv'] - evolve['old_lv']\n",
    "evolve = evolve.rename(columns={'num': 'lv_consume_item_num'})\n",
    "#print(evolve.head())\n",
    "\n",
    "# 计算每个角色每天升级了多少次\n",
    "tmp = evolve.groupby(['role_id', 'day'])['type'].size().reset_index(name='upgrade_type_counts')\n",
    "data = data.merge(tmp, on=['role_id', 'day'], how='left')\n",
    "\n",
    "# 计算每个角色每天升级道具使用了多少次\n",
    "tmp = evolve.groupby(['role_id', 'day'])['item_id'].size().reset_index(name='item_usage_counts')\n",
    "data = data.merge(tmp, on=['role_id', 'day'], how='left')\n",
    "\n",
    "# 计算每个角色每天升了多少级\n",
    "tmp = evolve.groupby(['role_id', 'day'])['n_level_up'].sum().reset_index(name='total_levels_upgraded')\n",
    "data = data.merge(tmp, on=['role_id', 'day'], how='left')\n",
    "\n",
    "# 计算每个角色每天平均升了多少级\n",
    "tmp = evolve.groupby(['role_id', 'day'])['n_level_up'].mean().reset_index(name='average_levels_upgraded')\n",
    "data = data.merge(tmp, on=['role_id', 'day'], how='left')\n",
    "\n",
    "# 计算每个角色每天升级道具一共使用的数量\n",
    "tmp = evolve.groupby(['role_id', 'day'])['lv_consume_item_num'].sum().reset_index(name='total_items_used')\n",
    "data = data.merge(tmp, on=['role_id', 'day'], how='left')\n",
    "\n",
    "# 计算每个角色每天升级道具平均使用的数量\n",
    "tmp = evolve.groupby(['role_id', 'day'])['lv_consume_item_num'].mean().reset_index(name='average_items_used')\n",
    "data = data.merge(tmp, on=['role_id', 'day'], how='left')\n",
    "\n",
    "print(data.head())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "e54fd2ff-3402-4dab-b27d-fbec9acf21f7",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "                        role_id  day  fb_result  fb_result_count\n",
      "0      0004e5689a52dfab4e797560    8          1               20\n",
      "1      0004e5689a52dfab4e797560    8          0                1\n",
      "2      00056768c43760d2c02d123c    6          0                1\n",
      "3      00056768c43760d2c02d123c    7          1               16\n",
      "4      0005d2c46efeb6fc65d96968    3          1                3\n",
      "...                         ...  ...        ...              ...\n",
      "42582  fff499a0e130830c4702c28d    4          1               21\n",
      "42583  fff499a0e130830c4702c28d    4          0                1\n",
      "42584  fff69da8c7aea3f86b85f0c3    2          2                5\n",
      "42585  fff69da8c7aea3f86b85f0c3    2          0                2\n",
      "42586  fff69da8c7aea3f86b85f0c3    2          1                2\n",
      "\n",
      "[42587 rows x 4 columns]\n",
      "                    role_id  create_time  day  use_t1_count  use_t1_sum  \\\n",
      "0  28b9114a5784b724997257c3   1593268403    2           1.0      -398.0   \n",
      "1  51d43143f0e8c695792ee1d4   1613439868    2          31.0       135.0   \n",
      "2  52f2bb2665cdb5d81dd245ba   1612927043    2           5.0     -1464.0   \n",
      "3  1f3c325b343a3f56b898265e   1614044315    2          12.0       -20.0   \n",
      "4  76d3a7bd0a8ed2b011a99aae   1614056679    2           5.0      -140.0   \n",
      "\n",
      "   use_t2_count  use_t2_sum  use_t3_count  use_t3_sum  use_t4_count  ...  \\\n",
      "0           1.0         0.0           1.0         0.0           1.0  ...   \n",
      "1          31.0         0.0          31.0         0.0          31.0  ...   \n",
      "2           5.0         0.0           5.0         0.0           5.0  ...   \n",
      "3          12.0         0.0          12.0         0.0          12.0  ...   \n",
      "4           5.0         0.0           5.0         0.0           5.0  ...   \n",
      "\n",
      "   total_items_used  average_items_used  total_attempts  average_time_fb  \\\n",
      "0               NaN                 NaN             NaN              NaN   \n",
      "1              49.0                 1.0             6.0       117.833333   \n",
      "2               5.0                 1.0             NaN              NaN   \n",
      "3              40.0                 1.0             3.0        69.000000   \n",
      "4               NaN                 NaN             NaN              NaN   \n",
      "\n",
      "   total_time_fb  average_exp_fb  total_exp_fb  fb_result0_count  \\\n",
      "0            NaN             NaN           NaN               NaN   \n",
      "1          707.0    2.276817e+07   136609046.0               3.0   \n",
      "2            NaN             NaN           NaN               NaN   \n",
      "3          207.0    5.765390e+07   172961695.0               1.0   \n",
      "4            NaN             NaN           NaN               NaN   \n",
      "\n",
      "   fb_result1_count  fb_result2_count  \n",
      "0               NaN               NaN  \n",
      "1               3.0               NaN  \n",
      "2               NaN               NaN  \n",
      "3               2.0               NaN  \n",
      "4               NaN               NaN  \n",
      "\n",
      "[5 rows x 25 columns]\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "'以上代码块主要涉及了对玩家副本挑战表的处理，提取了各种统计信息到了 data 数据中。'"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 读取副本表数据并进行日期处理\n",
    "fb = pd.read_csv(r'D:\\作业\\机器学习\\CCF BDCI\\role_fb_op.csv')\n",
    "fb['dt'] = pd.to_datetime(fb['dt'])  # 将日期列转换为 Pandas 的日期时间格式\n",
    "fb['day'] = fb['dt'].dt.day  # 提取日期中的天数，并创建 'day' 列\n",
    "fb['fb_used_time'] = fb['finish_time'] - fb['start_time']  # 计算副本的使用时间\n",
    "#print(fb.head())\n",
    "\n",
    "# 计算某角色某天打副本的总尝试次数\n",
    "tmp = fb.groupby(['role_id', 'day'])['fb_id'].size().reset_index(name='total_attempts')\n",
    "data = data.merge(tmp, on=['role_id', 'day'], how='left')\n",
    "\n",
    "# 计算某角色某天打副本的平均用时\n",
    "tmp = fb.groupby(['role_id', 'day'])['fb_used_time'].mean().reset_index(name='average_time_fb')\n",
    "data = data.merge(tmp, on=['role_id', 'day'], how='left')\n",
    "\n",
    "# 计算某角色某天打副本的总用时\n",
    "tmp = fb.groupby(['role_id', 'day'])['fb_used_time'].sum().reset_index(name='total_time_fb')\n",
    "data = data.merge(tmp, on=['role_id', 'day'], how='left')\n",
    "\n",
    "# 计算某角色某天打副本获得的平均经验\n",
    "tmp = fb.groupby(['role_id', 'day'])['exp'].mean().reset_index(name='average_exp_fb')\n",
    "data = data.merge(tmp, on=['role_id', 'day'], how='left')\n",
    "\n",
    "# 计算某角色某天打副本获得的总经验\n",
    "tmp = fb.groupby(['role_id', 'day'])['exp'].sum().reset_index(name='total_exp_fb')\n",
    "data = data.merge(tmp, on=['role_id', 'day'], how='left')\n",
    "\n",
    "# 使用for循环遍历一个包含元素0, 1, 2的列表。在循环中，通过筛选出fb_result等于当前循环变量i的子DataFrame，\n",
    "# 将该子DataFrame的列名修改为除最后一列外的所有列名加上'fb_result{i}_count'。这样可以为每个fb_result的取值创建一个对应的列。\n",
    "tmp = fb.groupby(['role_id', 'day'])['fb_result'].value_counts().reset_index(name='fb_result_count')\n",
    "print(tmp)\n",
    "for i in [0, 1, 2]:\n",
    "    tt = tmp[tmp['fb_result'] == i]\n",
    "    tt.columns = list(tt.columns[:-1]) + ['fb_result%d_count' % i]\n",
    "    data = data.merge(tt[['role_id', 'day', 'fb_result%d_count' % i]], on=['role_id', 'day'], how='left')\n",
    "\n",
    "\n",
    "# 检查合并后数据表的数据\n",
    "print(data.head())\n",
    "\n",
    "\"以上代码块主要涉及了对玩家副本挑战表的处理，提取了各种统计信息到了 data 数据中。\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "ebbfae89-96cb-4ee3-9449-c36b3635c541",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "                    role_id  create_time  day  use_t1_count  use_t1_sum  \\\n",
      "0  28b9114a5784b724997257c3   1593268403    2           1.0      -398.0   \n",
      "1  51d43143f0e8c695792ee1d4   1613439868    2          31.0       135.0   \n",
      "2  52f2bb2665cdb5d81dd245ba   1612927043    2           5.0     -1464.0   \n",
      "3  1f3c325b343a3f56b898265e   1614044315    2          12.0       -20.0   \n",
      "4  76d3a7bd0a8ed2b011a99aae   1614056679    2           5.0      -140.0   \n",
      "\n",
      "   use_t2_count  use_t2_sum  use_t3_count  use_t3_sum  use_t4_count  ...  \\\n",
      "0           1.0         0.0           1.0         0.0           1.0  ...   \n",
      "1          31.0         0.0          31.0         0.0          31.0  ...   \n",
      "2           5.0         0.0           5.0         0.0           5.0  ...   \n",
      "3          12.0         0.0          12.0         0.0          12.0  ...   \n",
      "4           5.0         0.0           5.0         0.0           5.0  ...   \n",
      "\n",
      "   total_time_fb  average_exp_fb  total_exp_fb  fb_result0_count  \\\n",
      "0            NaN             NaN           NaN               NaN   \n",
      "1          707.0    2.276817e+07   136609046.0               3.0   \n",
      "2            NaN             NaN           NaN               NaN   \n",
      "3          207.0    5.765390e+07   172961695.0               1.0   \n",
      "4            NaN             NaN           NaN               NaN   \n",
      "\n",
      "   fb_result1_count  fb_result2_count  mission_id_day_count  \\\n",
      "0               NaN               NaN                   NaN   \n",
      "1               3.0               NaN                   NaN   \n",
      "2               NaN               NaN                  23.0   \n",
      "3               2.0               NaN                   NaN   \n",
      "4               NaN               NaN                  10.0   \n",
      "\n",
      "   mission_id_day_nunique  mission_type_day_count  mission_type_day_nunique  \n",
      "0                     NaN                     NaN                       NaN  \n",
      "1                     NaN                     NaN                       NaN  \n",
      "2                     9.0                    23.0                       2.0  \n",
      "3                     NaN                     NaN                       NaN  \n",
      "4                     4.0                    10.0                       1.0  \n",
      "\n",
      "[5 rows x 29 columns]\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "'以上代码块主要涉及了对玩家任务系统表的处理，提取了各种统计信息到了 data 数据中。'"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 读取任务系统表数据并进行日期处理\n",
    "mission = pd.read_csv(r'D:\\作业\\机器学习\\CCF BDCI\\role_mission_op.csv')\n",
    "mission['dt'] = pd.to_datetime(mission['dt'])  # 将日期列转换为 Pandas 的日期时间格式\n",
    "mission['day'] = mission['dt'].dt.day  # 提取日期中的天数，并创建 'day' 列\n",
    "\n",
    "# 针对特定列进行循环处理，计算其统计信息并合并到 data 数据中\n",
    "for col in ['mission_id', 'mission_type']:\n",
    "    for m in ['count', 'nunique']:  # 计算计数和唯一值数量\n",
    "        tmp = mission.groupby(['role_id', 'day'])[col].agg(m).to_frame(name=f'{col}_day_{m}').reset_index()\n",
    "        data = data.merge(tmp, on=['role_id', 'day'], how='left')\n",
    "        \n",
    "# 检查合并后数据表的数据\n",
    "print(data.head())\n",
    "\"以上代码块主要涉及了对玩家任务系统表的处理，提取了各种统计信息到了 data 数据中。\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "id": "23329453-791e-4916-be6c-99c91b1f285f",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "                    role_id  create_time  day  use_t1_count  use_t1_sum  \\\n",
      "0  28b9114a5784b724997257c3   1593268403    2           1.0      -398.0   \n",
      "1  51d43143f0e8c695792ee1d4   1613439868    2          31.0       135.0   \n",
      "2  52f2bb2665cdb5d81dd245ba   1612927043    2           5.0     -1464.0   \n",
      "3  1f3c325b343a3f56b898265e   1614044315    2          12.0       -20.0   \n",
      "4  76d3a7bd0a8ed2b011a99aae   1614056679    2           5.0      -140.0   \n",
      "\n",
      "   use_t2_count  use_t2_sum  use_t3_count  use_t3_sum  use_t4_count  ...  \\\n",
      "0           1.0         0.0           1.0         0.0           1.0  ...   \n",
      "1          31.0         0.0          31.0         0.0          31.0  ...   \n",
      "2           5.0         0.0           5.0         0.0           5.0  ...   \n",
      "3          12.0         0.0          12.0         0.0          12.0  ...   \n",
      "4           5.0         0.0           5.0         0.0           5.0  ...   \n",
      "\n",
      "   mission_id_day_count  mission_id_day_nunique  mission_type_day_count  \\\n",
      "0                   NaN                     NaN                     NaN   \n",
      "1                   NaN                     NaN                     NaN   \n",
      "2                  23.0                     9.0                    23.0   \n",
      "3                   NaN                     NaN                     NaN   \n",
      "4                  10.0                     4.0                    10.0   \n",
      "\n",
      "   mission_type_day_nunique  reason_day_count  reason_day_nunique  \\\n",
      "0                       NaN               2.0                 1.0   \n",
      "1                       NaN               3.0                 3.0   \n",
      "2                       2.0               3.0                 2.0   \n",
      "3                       NaN               2.0                 1.0   \n",
      "4                       1.0               1.0                 1.0   \n",
      "\n",
      "   map_id_day_count  map_id_day_nunique  online_durations_day_mean  \\\n",
      "0               2.0                 1.0                 352.500000   \n",
      "1               3.0                 3.0                1337.333333   \n",
      "2               3.0                 1.0                 269.666667   \n",
      "3               2.0                 2.0                 344.500000   \n",
      "4               1.0                 1.0                 100.000000   \n",
      "\n",
      "   online_durations_day_sum  \n",
      "0                     705.0  \n",
      "1                    4012.0  \n",
      "2                     809.0  \n",
      "3                     689.0  \n",
      "4                     100.0  \n",
      "\n",
      "[5 rows x 35 columns]\n"
     ]
    }
   ],
   "source": [
    "# 读取玩家离线数据并进行日期处理\n",
    "offline = pd.read_csv(r'D:\\作业\\机器学习\\CCF BDCI\\role_offline_op.csv')\n",
    "offline['dt'] = pd.to_datetime(mission['dt'])  # 将日期列转换为 Pandas 的日期时间格式\n",
    "offline['day'] = offline['dt'].dt.day  # 提取日期中的天数，并创建 'day' 列\n",
    "offline['online_durations'] = offline['offline'] - offline['online']  # 计算在线时长\n",
    "\n",
    "# 针对特定列进行循环处理，计算其统计信息并合并到 data 数据中\n",
    "for col in ['reason', 'map_id']:\n",
    "    for m in ['count', 'nunique']:  # 计算计数和唯一值数量\n",
    "        tmp = offline.groupby(['role_id', 'day'])[col].agg(m).to_frame(name=f'{col}_day_{m}').reset_index()\n",
    "        data = data.merge(tmp, on=['role_id', 'day'], how='left')\n",
    "\n",
    "# 针对特定列进行循环处理，计算其统计信息并合并到 data 数据中\n",
    "for col in ['online_durations']:\n",
    "    for m in ['mean', 'sum']:  # 计算平均值和求和\n",
    "        tmp = offline.groupby(['role_id', 'day'])[col].agg(m).to_frame(name=f'{col}_day_{m}').reset_index()\n",
    "        data = data.merge(tmp, on=['role_id', 'day'], how='left')\n",
    "print(data.head())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "id": "63f45670-6285-4146-80b6-05819e9af091",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "                    role_id  create_time  day  use_t1_count  use_t1_sum  \\\n",
      "0  28b9114a5784b724997257c3   1593268403    2           1.0      -398.0   \n",
      "1  51d43143f0e8c695792ee1d4   1613439868    2          31.0       135.0   \n",
      "2  52f2bb2665cdb5d81dd245ba   1612927043    2           5.0     -1464.0   \n",
      "3  1f3c325b343a3f56b898265e   1614044315    2          12.0       -20.0   \n",
      "4  76d3a7bd0a8ed2b011a99aae   1614056679    2           5.0      -140.0   \n",
      "\n",
      "   use_t2_count  use_t2_sum  use_t3_count  use_t3_sum  use_t4_count  ...  \\\n",
      "0           1.0         0.0           1.0         0.0           1.0  ...   \n",
      "1          31.0         0.0          31.0         0.0          31.0  ...   \n",
      "2           5.0         0.0           5.0         0.0           5.0  ...   \n",
      "3          12.0         0.0          12.0         0.0          12.0  ...   \n",
      "4           5.0         0.0           5.0         0.0           5.0  ...   \n",
      "\n",
      "   mission_id_day_nunique  mission_type_day_count  mission_type_day_nunique  \\\n",
      "0                     NaN                     NaN                       NaN   \n",
      "1                     NaN                     NaN                       NaN   \n",
      "2                     9.0                    23.0                       2.0   \n",
      "3                     NaN                     NaN                       NaN   \n",
      "4                     4.0                    10.0                       1.0   \n",
      "\n",
      "   reason_day_count  reason_day_nunique  map_id_day_count  map_id_day_nunique  \\\n",
      "0               2.0                 1.0               2.0                 1.0   \n",
      "1               3.0                 3.0               3.0                 3.0   \n",
      "2               3.0                 2.0               3.0                 1.0   \n",
      "3               2.0                 1.0               2.0                 2.0   \n",
      "4               1.0                 1.0               1.0                 1.0   \n",
      "\n",
      "   online_durations_day_mean  online_durations_day_sum  pay_sum_day  \n",
      "0                 352.500000                     705.0          NaN  \n",
      "1                1337.333333                    4012.0          NaN  \n",
      "2                 269.666667                     809.0          NaN  \n",
      "3                 344.500000                     689.0          NaN  \n",
      "4                 100.000000                     100.0          NaN  \n",
      "\n",
      "[5 rows x 36 columns]\n"
     ]
    }
   ],
   "source": [
    "# 读取付费表数据并进行日期处理\n",
    "pay = pd.read_csv(r'D:\\作业\\机器学习\\CCF BDCI\\role_pay.csv')\n",
    "pay['dt'] = pd.to_datetime(pay['dt'])  # 将日期列转换为 Pandas 的日期时间格式\n",
    "pay['day'] = pay['dt'].dt.day  # 提取日期中的天数，并创建 'day' 列\n",
    "\n",
    "# 按照角色和天数进行分组，计算每天的付费金额总和\n",
    "tmp = pay.groupby(['role_id', 'day'])['pay'].agg('sum').to_frame(name='pay_sum_day').reset_index()\n",
    "\n",
    "# 将每天的付费金额总和合并到 data 数据中\n",
    "data = data.merge(tmp, on=['role_id', 'day'], how='left')\n",
    "\n",
    "print(data.head())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "id": "34fa0363-2a02-4b29-b98e-40f9499e3ec0",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "role_id                          0\n",
      "create_time                      0\n",
      "day                              0\n",
      "use_t1_count                 53982\n",
      "use_t1_sum                   53982\n",
      "use_t2_count                 53982\n",
      "use_t2_sum                   53982\n",
      "use_t3_count                 53982\n",
      "use_t3_sum                   53982\n",
      "use_t4_count                 53982\n",
      "use_t4_sum                   53982\n",
      "upgrade_type_counts          60334\n",
      "item_usage_counts            60334\n",
      "total_levels_upgraded        60334\n",
      "average_levels_upgraded      60334\n",
      "total_items_used             60334\n",
      "average_items_used           60334\n",
      "total_attempts               54858\n",
      "average_time_fb              54858\n",
      "total_time_fb                54858\n",
      "average_exp_fb               54858\n",
      "total_exp_fb                 54858\n",
      "fb_result0_count             59540\n",
      "fb_result1_count             56087\n",
      "fb_result2_count             68166\n",
      "mission_id_day_count         59351\n",
      "mission_id_day_nunique       59351\n",
      "mission_type_day_count       59351\n",
      "mission_type_day_nunique     59351\n",
      "reason_day_count             64764\n",
      "reason_day_nunique           64764\n",
      "map_id_day_count             64764\n",
      "map_id_day_nunique           64764\n",
      "online_durations_day_mean    64764\n",
      "online_durations_day_sum     64764\n",
      "pay_sum_day                  72935\n",
      "dtype: int64\n",
      "role_id                      0\n",
      "create_time                  0\n",
      "day                          0\n",
      "use_t1_count                 0\n",
      "use_t1_sum                   0\n",
      "use_t2_count                 0\n",
      "use_t2_sum                   0\n",
      "use_t3_count                 0\n",
      "use_t3_sum                   0\n",
      "use_t4_count                 0\n",
      "use_t4_sum                   0\n",
      "upgrade_type_counts          0\n",
      "item_usage_counts            0\n",
      "total_levels_upgraded        0\n",
      "average_levels_upgraded      0\n",
      "total_items_used             0\n",
      "average_items_used           0\n",
      "total_attempts               0\n",
      "average_time_fb              0\n",
      "total_time_fb                0\n",
      "average_exp_fb               0\n",
      "total_exp_fb                 0\n",
      "fb_result0_count             0\n",
      "fb_result1_count             0\n",
      "fb_result2_count             0\n",
      "mission_id_day_count         0\n",
      "mission_id_day_nunique       0\n",
      "mission_type_day_count       0\n",
      "mission_type_day_nunique     0\n",
      "reason_day_count             0\n",
      "reason_day_nunique           0\n",
      "map_id_day_count             0\n",
      "map_id_day_nunique           0\n",
      "online_durations_day_mean    0\n",
      "online_durations_day_sum     0\n",
      "pay_sum_day                  0\n",
      "dtype: int64\n"
     ]
    }
   ],
   "source": [
    "# 对data数据集中的所有缺失值进行处理，处理方法为全置0\n",
    "# 打印data中缺失值的数量\n",
    "print(data.isnull().sum())\n",
    "# 缺失我们把其当作0即可\n",
    "data = data.fillna(0) \n",
    "# 打印data中缺失值的数量\n",
    "print(data.isnull().sum())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "id": "2738777e-29f3-4884-a5f0-1ebf0b161bba",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "                    role_id  use_t1_count_day0  use_t1_sum_day0  \\\n",
      "0  28b9114a5784b724997257c3                1.0           -398.0   \n",
      "1  51d43143f0e8c695792ee1d4               31.0            135.0   \n",
      "2  52f2bb2665cdb5d81dd245ba                5.0          -1464.0   \n",
      "3  1f3c325b343a3f56b898265e               12.0            -20.0   \n",
      "4  76d3a7bd0a8ed2b011a99aae                5.0           -140.0   \n",
      "\n",
      "   use_t2_count_day0  use_t2_sum_day0  use_t3_count_day0  use_t3_sum_day0  \\\n",
      "0                1.0              0.0                1.0              0.0   \n",
      "1               31.0              0.0               31.0              0.0   \n",
      "2                5.0              0.0                5.0              0.0   \n",
      "3               12.0              0.0               12.0              0.0   \n",
      "4                5.0              0.0                5.0              0.0   \n",
      "\n",
      "   use_t4_count_day0  use_t4_sum_day0  upgrade_type_counts_day0  ...  \\\n",
      "0                1.0              0.0                       0.0  ...   \n",
      "1               31.0              0.0                      49.0  ...   \n",
      "2                5.0              0.0                       5.0  ...   \n",
      "3               12.0              0.0                      40.0  ...   \n",
      "4                5.0              0.0                       0.0  ...   \n",
      "\n",
      "   mission_id_day_nunique_day5  mission_type_day_count_day5  \\\n",
      "0                          0.0                          0.0   \n",
      "1                          0.0                          0.0   \n",
      "2                          0.0                          0.0   \n",
      "3                          0.0                          0.0   \n",
      "4                          0.0                          0.0   \n",
      "\n",
      "   mission_type_day_nunique_day5  reason_day_count_day5  \\\n",
      "0                            0.0                    0.0   \n",
      "1                            0.0                    0.0   \n",
      "2                            0.0                    0.0   \n",
      "3                            0.0                    0.0   \n",
      "4                            0.0                    0.0   \n",
      "\n",
      "   reason_day_nunique_day5  map_id_day_count_day5  map_id_day_nunique_day5  \\\n",
      "0                      0.0                    0.0                      0.0   \n",
      "1                      0.0                    0.0                      0.0   \n",
      "2                      0.0                    0.0                      0.0   \n",
      "3                      0.0                    0.0                      0.0   \n",
      "4                      0.0                    0.0                      0.0   \n",
      "\n",
      "   online_durations_day_mean_day5  online_durations_day_sum_day5  \\\n",
      "0                             0.0                            0.0   \n",
      "1                             0.0                            0.0   \n",
      "2                             0.0                            0.0   \n",
      "3                             0.0                            0.0   \n",
      "4                             0.0                            0.0   \n",
      "\n",
      "   pay_sum_day_day5  \n",
      "0               0.0  \n",
      "1               0.0  \n",
      "2               0.0  \n",
      "3               0.0  \n",
      "4               0.0  \n",
      "\n",
      "[5 rows x 199 columns]\n"
     ]
    }
   ],
   "source": [
    "\n",
    "# 创建初步训练集：使用前 6 天的行为预测第 7 天的付费情况\n",
    "# 创建一个空的DataFrame对象df_train，并将一个列名为’role_id’的列添加到其中。列的值来自于数据集data中的role_id列去重后得到的唯一值列表。\n",
    "df_train = pd.DataFrame({'role_id': data.role_id.unique().tolist()})\n",
    "for i, d in enumerate(range(2, 8)):\n",
    "    #根据data中的day列的值等于d的条件，筛选出满足条件的子数据集，并将其赋值给临时变量tmp\n",
    "    tmp = data[data.day == d].copy().reset_index(drop=True)\n",
    "    #丢弃create_time、day两列 axis=1表示删除列，inplace=True表示在原数据上进行操作\n",
    "    tmp.drop(['create_time', 'day'], axis=1, inplace=True)\n",
    "    tmp.columns = ['role_id'] + [f'{c}_day{i}' for c in tmp.columns[1:]]\n",
    "    df_train = df_train.merge(tmp, on='role_id')\n",
    "\n",
    "print(df_train.head())\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "id": "279a1860-0360-440f-a041-2170ab72df4e",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "                    role_id  use_t1_count_day0  use_t1_sum_day0  \\\n",
      "0  28b9114a5784b724997257c3                1.0           -398.0   \n",
      "1  51d43143f0e8c695792ee1d4               31.0            135.0   \n",
      "2  52f2bb2665cdb5d81dd245ba                5.0          -1464.0   \n",
      "3  1f3c325b343a3f56b898265e               12.0            -20.0   \n",
      "4  76d3a7bd0a8ed2b011a99aae                5.0           -140.0   \n",
      "\n",
      "   use_t2_count_day0  use_t2_sum_day0  use_t3_count_day0  use_t3_sum_day0  \\\n",
      "0                1.0              0.0                1.0              0.0   \n",
      "1               31.0              0.0               31.0              0.0   \n",
      "2                5.0              0.0                5.0              0.0   \n",
      "3               12.0              0.0               12.0              0.0   \n",
      "4                5.0              0.0                5.0              0.0   \n",
      "\n",
      "   use_t4_count_day0  use_t4_sum_day0  upgrade_type_counts_day0  ...  \\\n",
      "0                1.0              0.0                       0.0  ...   \n",
      "1               31.0              0.0                      49.0  ...   \n",
      "2                5.0              0.0                       5.0  ...   \n",
      "3               12.0              0.0                      40.0  ...   \n",
      "4                5.0              0.0                       0.0  ...   \n",
      "\n",
      "   mission_type_day_count_day5  mission_type_day_nunique_day5  \\\n",
      "0                          0.0                            0.0   \n",
      "1                          0.0                            0.0   \n",
      "2                          0.0                            0.0   \n",
      "3                          0.0                            0.0   \n",
      "4                          0.0                            0.0   \n",
      "\n",
      "   reason_day_count_day5  reason_day_nunique_day5  map_id_day_count_day5  \\\n",
      "0                    0.0                      0.0                    0.0   \n",
      "1                    0.0                      0.0                    0.0   \n",
      "2                    0.0                      0.0                    0.0   \n",
      "3                    0.0                      0.0                    0.0   \n",
      "4                    0.0                      0.0                    0.0   \n",
      "\n",
      "   map_id_day_nunique_day5  online_durations_day_mean_day5  \\\n",
      "0                      0.0                             0.0   \n",
      "1                      0.0                             0.0   \n",
      "2                      0.0                             0.0   \n",
      "3                      0.0                             0.0   \n",
      "4                      0.0                             0.0   \n",
      "\n",
      "   online_durations_day_sum_day5  pay_sum_day_day5  seventh_pay  \n",
      "0                            0.0               0.0          0.0  \n",
      "1                            0.0               0.0          0.0  \n",
      "2                            0.0               0.0          0.0  \n",
      "3                            0.0               0.0          0.0  \n",
      "4                            0.0               0.0          0.0  \n",
      "\n",
      "[5 rows x 200 columns]\n"
     ]
    }
   ],
   "source": [
    "# 创建最终训练集\n",
    "# 从付费表中提取初步训练集的标签\n",
    "day8_pay = pay[pay.day == 8].copy().reset_index(drop=True)\n",
    "tmp = day8_pay.groupby('role_id')['pay'].agg('sum').to_frame(name='seventh_pay').reset_index()\n",
    "df_train = df_train.merge(tmp, on='role_id', how='left')\n",
    "df_train['seventh_pay'].fillna(0., inplace=True)  # 对于缺失值填充为 0.0\n",
    "print(df_train.head())\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "id": "2f1d27fe-f306-4e90-9be8-3b708290cc27",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "   use_t1_count_day0  use_t1_sum_day0  use_t2_count_day0  use_t2_sum_day0  \\\n",
      "0                1.0           -398.0                1.0              0.0   \n",
      "1               31.0            135.0               31.0              0.0   \n",
      "2                5.0              0.0                5.0              0.0   \n",
      "3               12.0            -20.0               12.0              0.0   \n",
      "4                5.0           -140.0                5.0              0.0   \n",
      "\n",
      "   use_t3_count_day0  use_t3_sum_day0  use_t4_count_day0  use_t4_sum_day0  \\\n",
      "0                1.0              0.0                1.0              0.0   \n",
      "1               31.0              0.0               31.0              0.0   \n",
      "2                5.0              0.0                5.0              0.0   \n",
      "3               12.0              0.0               12.0              0.0   \n",
      "4                5.0              0.0                5.0              0.0   \n",
      "\n",
      "   upgrade_type_counts_day0  item_usage_counts_day0  ...  \\\n",
      "0                       0.0                     0.0  ...   \n",
      "1                      49.0                    49.0  ...   \n",
      "2                       5.0                     5.0  ...   \n",
      "3                      40.0                    40.0  ...   \n",
      "4                       0.0                     0.0  ...   \n",
      "\n",
      "   mission_type_day_count_day5  mission_type_day_nunique_day5  \\\n",
      "0                          0.0                            0.0   \n",
      "1                          0.0                            0.0   \n",
      "2                          0.0                            0.0   \n",
      "3                          0.0                            0.0   \n",
      "4                          0.0                            0.0   \n",
      "\n",
      "   reason_day_count_day5  reason_day_nunique_day5  map_id_day_count_day5  \\\n",
      "0                    0.0                      0.0                    0.0   \n",
      "1                    0.0                      0.0                    0.0   \n",
      "2                    0.0                      0.0                    0.0   \n",
      "3                    0.0                      0.0                    0.0   \n",
      "4                    0.0                      0.0                    0.0   \n",
      "\n",
      "   map_id_day_nunique_day5  online_durations_day_mean_day5  \\\n",
      "0                      0.0                             0.0   \n",
      "1                      0.0                             0.0   \n",
      "2                      0.0                             0.0   \n",
      "3                      0.0                             0.0   \n",
      "4                      0.0                             0.0   \n",
      "\n",
      "   online_durations_day_sum_day5  pay_sum_day_day5  seventh_pay  \n",
      "0                            0.0               0.0          0.0  \n",
      "1                            0.0               0.0          0.0  \n",
      "2                            0.0               0.0          0.0  \n",
      "3                            0.0               0.0          0.0  \n",
      "4                            0.0               0.0          0.0  \n",
      "\n",
      "[5 rows x 199 columns]\n"
     ]
    }
   ],
   "source": [
    "# 集中处理最终训练集\n",
    "\n",
    "# 首先，由于每个用户id不同，训练时必须把id剔除。否则这类特征通常是高基数分类特征，这意味着它们包含大量唯一项。\n",
    "# 对此类特征进行独热编码通常不可行，因为这会生成大量的特征，导致维度过高，这个问题也被称为“维度灾难”\n",
    "#剔除最终训练集中的role_id\n",
    "df_train = df_train.drop(columns=['role_id'])\n",
    "\n",
    "# 定义一个异常值处理函数\n",
    "def handle_outliers(df, method='zscore', threshold=3):\n",
    "    numerical_features = df.select_dtypes(include=[np.number])  # 选择数值型特征\n",
    "    if method == 'zscore':\n",
    "        # 使用Z-score方法识别异常值\n",
    "        for feature in numerical_features:\n",
    "            df_feature = df[feature]\n",
    "            z_scores = (df_feature - df_feature.mean()) / df_feature.std()\n",
    "            outliers = abs(z_scores) > threshold\n",
    "            df[feature][outliers] = df_feature.median()  # 用中位数替换异常值\n",
    "    elif method == 'iqr':\n",
    "        # 使用四分位数间距(IQR)方法识别异常值\n",
    "        for feature in numerical_features:\n",
    "            df_feature = df[feature]\n",
    "            Q1 = df_feature.quantile(0.25)\n",
    "            Q3 = df_feature.quantile(0.75)\n",
    "            IQR = Q3 - Q1\n",
    "            lower_bound = Q1 - (1.5 * IQR)\n",
    "            upper_bound = Q3 + (1.5 * IQR)\n",
    "            df[feature] = np.where((df_feature < lower_bound), df_feature.median(), df_feature)  # 下界异常值替换\n",
    "            df[feature] = np.where((df_feature > upper_bound), df_feature.median(), df_feature)  # 上界异常值替换\n",
    "    else:\n",
    "        raise ValueError(\"Invalid method. Use 'zscore' or 'iqr'.\")\n",
    "    return df\n",
    "\n",
    "# 在df_train数据集上应用异常值处理：\n",
    "df_train = handle_outliers(df_train, method='zscore', threshold=3)\n",
    "# df_train 现在是处理过异常值的DataFrame\n",
    "\n",
    "print(df_train.head())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "id": "1cb73522-340c-4b69-9681-d74bb1cae3d2",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "训练集特征数据的维度： (8624, 198)\n",
      "验证集特征数据的维度： (2156, 198)\n",
      "训练集目标变量的维度： (8624,)\n",
      "验证集目标变量的维度： (2156,)\n"
     ]
    }
   ],
   "source": [
    "# 最终训练集拆分，分为训练集和验证集，80%训练集和20%验证集\n",
    "# 分离特征和目标变量\n",
    "X = df_train.drop(columns=['seventh_pay'])  # 特征数据\n",
    "y = df_train['seventh_pay']                # 目标变量\n",
    "\n",
    "# 拆分数据集\n",
    "X_train, X_val, y_train, y_val = train_test_split(X, y, test_size=0.20, random_state=42)\n",
    "\n",
    "# 查看数据维度来确认拆分\n",
    "print(\"训练集特征数据的维度：\", X_train.shape)\n",
    "print(\"验证集特征数据的维度：\", X_val.shape)\n",
    "print(\"训练集目标变量的维度：\", y_train.shape)\n",
    "print(\"验证集目标变量的维度：\", y_val.shape)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "id": "4bc87e9b-e046-47cb-a4b9-0363728a1163",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "验证集的均方对数误差（MSLE）: 0.29\n",
      "均方对数误差分值： 0.7731064234296537\n"
     ]
    },
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAA0kAAAHWCAYAAACi1sL/AAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjguMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8g+/7EAAAACXBIWXMAAA9hAAAPYQGoP6dpAAC+h0lEQVR4nOzdd3wUZf4H8M9uSDY9IT0hDRBJEEQBBQSkiAciSNVT8cR2Z0EFy3ninShYsJwKnGfBH4J6iidVUQ8ElCogICAlhBZICOmQTUjP7vz++Dpbkk2ym2yym+Tzfr3ySjI7O/PMzDMzz3eeMhpFURQQERERERERAEDr6gQQERERERG5EwZJREREREREFhgkERERERERWWCQREREREREZIFBEhERERERkQUGSURERERERBYYJBEREREREVlgkERERERERGSBQRIREREREZEFBklERA7QaDR48cUXXZ2MJvvss8+QlJQET09PBAcHuzo5zeLMmTPQaDRYunSpq5NiMmzYMAwbNszVyWjQ0qVLodFocObMGdM0d0u7rTS2hM2bN0Oj0WDz5s0tul4ialkMkojIIadOncKDDz6ILl26wNvbG4GBgRg0aBAWLFiAsrIyVyeP7HDs2DHcc8896Nq1Kz766CMsWrTIru8988wz0Gg0+OMf/9jodR89ehQvvvhiixdsW5vExERoNBrTT0REBIYMGYLVq1e7OmkOKS0txYsvvuiygOLKK69EfHw8FEWpc55BgwYhMjIS1dXVLZgyInJ3HVydACJqPb777jvceuut0Ol0uPvuu9GzZ09UVlZi+/bt+Otf/4ojR47YXeBurcrKytChQ+u+dG7evBlGoxELFizAZZddZtd3FEXBsmXLkJiYiLVr16K4uBgBAQEOr/vo0aOYM2cOhg0bhsTERIe/355cddVVeOqppwAA58+fx4cffohJkybh/fffx0MPPdTi6fnhhx8c/k5paSnmzJkDAC6phZo6dSqeffZZbNu2Dddff32tz8+cOYOdO3fi0UcfbfXnNRE5F2uSiMguaWlpuP3225GQkICjR49iwYIF+POf/4zp06dj2bJlOHr0KK644gpXJ7NZGI1GlJeXAwC8vb1bfWEqNzcXABxqZrd582acO3cOH3/8Maqrq7Fq1apmSh2pOnXqhLvuugt33XUXnnnmGezYsQN+fn5455136vxOdXU1KisrmyU9Xl5e8PLyapZlN5c777wTGo0GX3zxhc3Ply1bBkVRMHXq1BZOGRG5OwZJRGSXN954A5cuXcLixYsRHR1d6/PLLrsMM2bMMP1fXV2Nl156CV27doVOp0NiYiKee+45VFRUWH0vMTERY8eOxebNm9GvXz/4+PigV69epuY5q1atQq9eveDt7Y2+ffti//79Vt+/55574O/vj9OnT2PUqFHw8/NDTEwM5s6dW6uJzT//+U9cd911CA0NhY+PD/r27YsVK1bU2haNRoNHH30Un3/+Oa644grodDqsW7fO9Jlln6Ti4mLMnDkTiYmJ0Ol0iIiIwI033ohff/3VapnLly9H37594ePjg7CwMNx1113IzMy0uS2ZmZmYMGEC/P39ER4ejqeffhoGg6GOI2PtvffeM6U5JiYG06dPR2FhodX+fuGFFwAA4eHhdvex+vzzz9GjRw8MHz4cI0eOxOeff25zvszMTNx///2IiYmBTqdD586d8fDDD6OyshJLly7FrbfeCgAYPny4qSmZeqzrSktiYiLuuece0/8XLlzA008/jV69esHf3x+BgYG46aabcPDgQbv2UU32Lk/ti/LVV1/hlVdeQWxsLLy9vXHDDTfg5MmTtZa7aNEidO3aFT4+Prj22muxbdu2RqVPFRUVheTkZKSlpQEw97n65z//ifnz55vOtaNHjwKQZpVTpkxBSEgIvL290a9fP3zzzTe1lnvkyBGMGDECPj4+iI2Nxcsvvwyj0VhrPlt9ksrLy/Hiiy/i8ssvh7e3N6KjozFp0iScOnUKZ86cQXh4OABgzpw5puNteYydncaa4uLicP3112PFihWoqqqq9fkXX3yBrl27on///jh79iweeeQRdO/eHT4+PggNDcWtt95qV9PQmnlUZWufVVRU4IUXXsBll10GnU6HuLg4PPPMM7WujRs2bMDgwYMRHBwMf39/dO/eHc8991yDaSEi52jdj0OJqMWsXbsWXbp0wXXXXWfX/A888AA++eQTTJkyBU899RR2796NefPmISUlpVa/ipMnT+LOO+/Egw8+iLvuugv//Oc/MW7cOHzwwQd47rnn8MgjjwAA5s2bh9tuuw2pqanQas3PeAwGA0aPHo0BAwbgjTfewLp16/DCCy+guroac+fONc23YMEC3HLLLZg6dSoqKyvx5Zdf4tZbb8W3336Lm2++2SpNP/74I7766is8+uijCAsLq7Np2EMPPYQVK1bg0UcfRY8ePVBQUIDt27cjJSUFffr0ASAdzO+9915cc801mDdvHnJycrBgwQLs2LED+/fvt6rRMRgMGDVqFPr3749//vOf2LhxI9566y107doVDz/8cL37/MUXX8ScOXMwcuRIPPzww0hNTcX777+PPXv2YMeOHfD09MT8+fPx6aefYvXq1Xj//ffh7++PK6+8st7lVlRUYOXKlaamX3fccQfuvfdeZGdnIyoqyjTf+fPnce2116KwsBB/+ctfkJSUhMzMTKxYsQKlpaW4/vrr8fjjj2PhwoV47rnnkJycDACm3/Y6ffo01qxZg1tvvRWdO3dGTk4OPvzwQwwdOhRHjx5FTExMsy7vtddeg1arxdNPPw29Xo833ngDU6dOxe7du03zLF68GA8++CCuu+46zJw5E6dPn8Ytt9yCkJAQxMXFOZQ+VVVVFTIyMhAaGmo1fcmSJSgvL8df/vIX6HQ6hISE4MiRIxg0aBA6deqEZ599Fn5+fvjqq68wYcIErFy5EhMnTgQAZGdnY/jw4aiurjbNt2jRIvj4+DSYHoPBgLFjx2LTpk24/fbbMWPGDBQXF2PDhg04fPgwRo4ciffffx8PP/wwJk6ciEmTJgGAKb+1RBoBaXL3l7/8BevXr8fYsWNN0w8dOoTDhw9j9uzZAIA9e/bg559/xu23347Y2FicOXMG77//PoYNG4ajR4/C19fXrvXVx2g04pZbbsH27dvxl7/8BcnJyTh06BDeeecdHD9+HGvWrDHtm7Fjx+LKK6/E3LlzodPpcPLkSezYsaPJaSAiOylERA3Q6/UKAGX8+PF2zX/gwAEFgPLAAw9YTX/66acVAMqPP/5ompaQkKAAUH7++WfTtPXr1ysAFB8fH+Xs2bOm6R9++KECQPnpp59M06ZNm6YAUB577DHTNKPRqNx8882Kl5eXkpeXZ5peWlpqlZ7KykqlZ8+eyogRI6ymA1C0Wq1y5MiRWtsGQHnhhRdM/wcFBSnTp0+vc19UVlYqERERSs+ePZWysjLT9G+//VYBoMyePbvWtsydO9dqGVdffbXSt2/fOtehKIqSm5ureHl5KX/4wx8Ug8Fgmv7uu+8qAJSPP/7YNO2FF15QAFjtm/qsWLFCAaCcOHFCURRFKSoqUry9vZV33nnHar67775b0Wq1yp49e2otw2g0KoqiKMuXL691DFU1960qISFBmTZtmun/8vJyq21UFEVJS0tTdDqd1b5LS0tTAChLliypd/vsXd5PP/2kAFCSk5OViooK0/QFCxYoAJRDhw4pimI+5ldddZXVfIsWLVIAKEOHDq03Peo2/+EPf1Dy8vKUvLw85eDBg8rtt99uldfV7QsMDFRyc3Otvn/DDTcovXr1UsrLy03TjEajct111yndunUzTZs5c6YCQNm9e7dpWm5urhIUFKQAUNLS0kzThw4dapX2jz/+WAGgvP3227XSrx7vvLy8Oo9rc6TRlgsXLig6nU654447rKY/++yzCgAlNTVVUZTa1wdFUZSdO3cqAJRPP/3UNE3NB5Z5uGYeVdXcZ5999pmi1WqVbdu2Wc33wQcfKACUHTt2KIqiKO+8845D5ygROR+b2xFRg4qKigDA7o7633//PQDgySeftJqu1kR89913VtN79OiBgQMHmv7v378/AGDEiBGIj4+vNf306dO11vnoo4+a/laby1VWVmLjxo2m6ZZPni9evAi9Xo8hQ4bUahoHAEOHDkWPHj0a2FLp17N7926cP3/e5ud79+5Fbm4uHnnkEXh7e5um33zzzUhKSqq1LwDU6pQ/ZMgQm9tsaePGjaisrMTMmTOtatn+/Oc/IzAw0OZ67PX555+jX79+pkEeAgICcPPNN1s1uTMajVizZg3GjRuHfv361VqGRqNp9Ppr0ul0pm00GAwoKCgwNUeydSydvbx7773Xqm/OkCFDAJjzpXrMH3roIav57rnnHgQFBdmdrh9++AHh4eEIDw9H7969sXz5cvzpT3/C66+/bjXf5MmTTc3aAGk++OOPP+K2225DcXEx8vPzkZ+fj4KCAowaNQonTpwwNfX8/vvvMWDAAFx77bWm74eHh9vVR2flypUICwvDY489Vuuzho53S6URADp27IgxY8bgm2++QUlJCQAZiOTLL79Ev379cPnllwOwvj5UVVWhoKAAl112GYKDgxuVr2xZvnw5kpOTkZSUZNrm/Px8jBgxAgDw008/ATD3F/z666/talZIRM7HIImIGhQYGAhA+t/Y4+zZs9BqtbVGTouKikJwcDDOnj1rNd0yEAJgKkjWbJakTr948aLVdK1Wiy5dulhNUws+lv0Jvv32WwwYMADe3t4ICQlBeHg43n//fej1+lrb0Llz54Y2E4D01Tp8+DDi4uJw7bXX4sUXX7QKaNRt7d69e63vJiUl1doX3t7eVgVeQAp5Nbe5prrW4+XlhS5dutRaj70KCwvx/fffY+jQoTh58qTpZ9CgQdi7dy+OHz8OAMjLy0NRURF69uzZqPU4wmg04p133kG3bt2g0+kQFhaG8PBw/PbbbzaPpbOXVzO/duzYEYA5X6r7ulu3blbzeXp61sqn9enfvz82bNiAjRs34ueff0Z+fj4+/fTTWs3MaubVkydPQlEUPP/886YgS/1R+6Opg3ecPXu2VjoB2/m1plOnTqF79+6NGsikpdKomjp1KkpKSvD1118DAH7++WecOXPGKtAqKyvD7NmzERcXZ5UPCgsLG5WvbDlx4gSOHDlSa5vV65W6zX/84x8xaNAgPPDAA4iMjMTtt9+Or776igETUQtinyQialBgYCBiYmJw+PBhh75nb+2Bh4eHQ9OVet55Updt27bhlltuwfXXX4/33nsP0dHR8PT0xJIlS2yOfGVvf4fbbrvN9P6aH374AW+++SZef/11rFq1CjfddJPD6axrm11l+fLlqKiowFtvvYW33nqr1ueff/65aYjn5lJz0IpXX30Vzz//PO677z689NJLCAkJgVarxcyZMxtViHR0ec7Ml/UJCwvDyJEjG5yvZl5V0/z0009j1KhRNr9j79DvzaWl0zh27FgEBQXhiy++wJ133okvvvgCHh4euP32203zPPbYY1iyZAlmzpyJgQMHIigoCBqNBrfffnuD+aqua53BYLDKL0ajEb169cLbb79tc371wZCPjw+2bt2Kn376Cd999x3WrVuH//73vxgxYgR++OEHt7tOELVFDJKIyC5jx47FokWLsHPnTqumcbYkJCTAaDTixIkTVp3yc3JyUFhYiISEBKemzWg04vTp06ansQBMNRzqgAsrV66Et7c31q9fD51OZ5pvyZIlTV5/dHQ0HnnkETzyyCPIzc1Fnz598Morr+Cmm24ybWtqaqqpSY0qNTXVafvCcj2WtRWVlZVIS0uzq7Bty+eff46ePXuanu5b+vDDD/HFF19gzpw5CA8PR2BgYIOBdH2Bc8eOHa1G4lPTn5WVZTVtxYoVGD58OBYvXmw1vbCwEGFhYQ1sUW3OXp56LE6cOGF1zKuqqpCWlobevXs7vExHqMff09OzweOekJCAEydO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iiuuUHQ6ndKxY0elb9++ypw5cxS9Xq8oiqJs2rRJGT9+vBITE6N4eXkpMTExyh133KEcP37c7m0loqbRKIqTe5oSEbWge+65BytWrMClS5dcnRQiIiJqI9gniYiIiIiIyAKDJCIiIiIiIgsMkoiIiIiIiCywTxIREREREZEF1iQRERERERFZYJBERERERERkoc2/TNZoNOL8+fMICAiARqNxdXKIiIiIiMhFFEVBcXExYmJioNXWXV/U5oOk8+fPIy4uztXJICIiIiIiN5GRkYHY2Ng6P2/zQVJAQAAA2RGBgYEuTg0REREREblKUVER4uLiTDFCXdp8kKQ2sQsMDGSQREREREREDXbD4cANREREREREFhgkERERERERWWCQREREREREZIFBEhERERERkQUGSURERERERBYYJBEREREREVlgkERERERERGSBQRIREREREZEFBklEREREREQWOrg6AUSOMBiAbduArCwgOhoYMgTw8HB1qtoe7ufWr6FjyGNMREQ18d5gxiCJWo1Vq4AZM4Bz58zTYmOBBQuASZNcl662hvu59WvoGPIYExFRTbw3WNMoiqK4OhHNqaioCEFBQdDr9QgMDHR1cqiRVq0CpkwBauZWjUZ+r1jRPk9gZ+N+bv0aOoZPPw388588xkREZNae7v/2xgYMksjtGQxAYqL1kw1LGo086UhLa79Vws7A/dz6NXQMATl2BoPtz3iMiYjan/Z2/7c3NuDADeT2tm2rv9CnKEBGhsxHjcf93Po1dAyBugMkgMeYiKg94v3fNgZJ5Payspw7H9nG/dz6OevY8BgTEbUfvP/bxiCJ3F50tHPnI9u4n1s/Zx0bHmMiovaD93/b2CeJ3J7aVjYzs3aHQqDttZV1Fe7n1q+hYwjIsTMaeYyJiEi0t/s/+yRRm+HhIcNPAuZRVlTq//Pnt40T15W4n1u/ho6hRgM8+WTdnwM8xkRE7Q3v/7YxSKJWYdIkGX6yUyfr6bGxbWtYSlfjfm79GjqGb7zBY0xERNZ4/6+Nze2oVeGboFsG93Pr19Ax5DEmIqKa2sO9ge9J+h2DJCIiIiIiAtgniYiIiIiIqFEYJBEREREREVlgkERERERERGSBQRIREREREZEFBklEREREREQWGCQRERERERFZYJBERERERERkgUESERERERGRBZcGSYmJidBoNLV+pk+fDgAoLy/H9OnTERoaCn9/f0yePBk5OTmuTDIREREREbVxLg2S9uzZg6ysLNPPhg0bAAC33norAOCJJ57A2rVrsXz5cmzZsgXnz5/HpEmTXJlkIiIiIiJq4zSKoiiuToRq5syZ+Pbbb3HixAkUFRUhPDwcX3zxBaZMmQIAOHbsGJKTk7Fz504MGDDArmUWFRUhKCgIer0egYGBzZl8IiIiIiJyY/bGBm7TJ6myshL/+c9/cN9990Gj0WDfvn2oqqrCyJEjTfMkJSUhPj4eO3furHM5FRUVKCoqsvohIiIiIiKyl9sESWvWrEFhYSHuueceAEB2dja8vLwQHBxsNV9kZCSys7PrXM68efMQFBRk+omLi2vGVBMRERERUVvjNkHS4sWLcdNNNyEmJqZJy5k1axb0er3pJyMjw0kpJCIiIiKi9qCDqxMAAGfPnsXGjRuxatUq07SoqChUVlaisLDQqjYpJycHUVFRdS5Lp9NBp9M1Z3KJiIiIiKgNc4uapCVLliAiIgI333yzaVrfvn3h6emJTZs2maalpqYiPT0dAwcOdEUyiYiIiIioHXB5TZLRaMSSJUswbdo0dOhgTk5QUBDuv/9+PPnkkwgJCUFgYCAee+wxDBw40O6R7YiIiIiIiBzl8iBp48aNSE9Px3333Vfrs3feeQdarRaTJ09GRUUFRo0ahffee88FqWybDAZg2zYgKwuIjgaGDAE8PFydKiIiaixe14lcj+dh2+BW70lqDnxPkm2rVgEzZgDnzpmnxcYCCxYAfF8vEVHrw+s6kevxPHR/re49SdRyVq0CpkyxPoEBIDNTpluMn0FERK0Ar+tErsfzsG1hTVI7YzAAiYm1T2CVRiNPPNLSWDVMRNQa8LpO5Ho8D1sP1iSRTdu21X0CA4CiABkZMh8REbk/XteJXI/nYdvDIKmdycpy7nxERORavK4TuR7Pw7aHQVI7Ex3t3PmIiMi1eF0ncj2eh20Pg6R2ZsgQaROr0dj+XKMB4uJkPiIicn+8rhO5Hs/DtodBUjvj4SHDUAK1T2T1//nz2amQiKi14HWdyPV4HrY9DJLaoUmTgBUrgE6drKfHxsp0juNPRNS68LpO5Ho8D9sWDgHejvGN0EREbQuv60Sux/PQvdkbGzBIIiIiIiKidoHvSSIiIiIiImoEBklEREREREQWGCQRERERERFZYJBERERERERkgUESERERERGRBQZJREREREREFhgkERERERERWWCQREREREREZIFBEhERERERkQUGSURERERERBYYJBEREREREVlgkERERERERGSBQRIREREREZEFBklEREREREQWGCQRERERERFZYJBERERERERkgUESERERERGRBQZJREREREREFhgkERERERERWWCQREREREREZIFBEhERERERkQUGSURERERERBYYJBEREREREVlgkERERERERGSBQRIREREREZEFBklEREREREQWGCQRERERERFZcHmQlJmZibvuuguhoaHw8fFBr169sHfvXtPniqJg9uzZiI6Oho+PD0aOHIkTJ064MMVERERERNSWuTRIunjxIgYNGgRPT0/873//w9GjR/HWW2+hY8eOpnneeOMNLFy4EB988AF2794NPz8/jBo1CuXl5S5MORERERERtVUaRVEUV6382WefxY4dO7Bt2zabnyuKgpiYGDz11FN4+umnAQB6vR6RkZFYunQpbr/99lrfqaioQEVFhen/oqIixMXFQa/XIzAwsHk2hIiIiIiI3F5RURGCgoIajA1cWpP0zTffoF+/frj11lsRERGBq6++Gh999JHp87S0NGRnZ2PkyJGmaUFBQejfvz927txpc5nz5s1DUFCQ6ScuLq7Zt4OIiIiIiNoOlwZJp0+fxvvvv49u3bph/fr1ePjhh/H444/jk08+AQBkZ2cDACIjI62+FxkZafqsplmzZkGv15t+MjIymncjiIiIiIioTengypUbjUb069cPr776KgDg6quvxuHDh/HBBx9g2rRpjVqmTqeDTqdzZjKJiIiIiKgdcWlNUnR0NHr06GE1LTk5Genp6QCAqKgoAEBOTo7VPDk5OabPiIiIiIiInMmlQdKgQYOQmppqNe348eNISEgAAHTu3BlRUVHYtGmT6fOioiLs3r0bAwcObNG0EhERERFR++DS5nZPPPEErrvuOrz66qu47bbb8Msvv2DRokVYtGgRAECj0WDmzJl4+eWX0a1bN3Tu3BnPP/88YmJiMGHCBFcmnYiIiIiI2iiXBknXXHMNVq9ejVmzZmHu3Lno3Lkz5s+fj6lTp5rmeeaZZ1BSUoK//OUvKCwsxODBg7Fu3Tp4e3u7MOVERERERNRWufQ9SS3B3rHQiYiIiIiobWsV70kiIiIiIiJyNwySiIiIiIiILDBIIiIiIiIissAgiYiIiIiIyAKDJCIiIiIiIgsMkoiIiIiIiCwwSCIiIiIiIrLAIImIiIiIiMgCgyQiIiIiIiILDJKIiIiIiIgsMEgiIiIiIiKywCCJiIiIiIjIAoMkIiIiIiIiCwySiIiIiIiILDBIIiIiIiIissAgiYiIiIiIyAKDJCIiIiIiIgsMkoiIiIiIiCwwSCIiIiIiIrLAIImIiIiIiMgCgyQiIiIiIiILDJKIiIiIiIgsMEgiIiIiIiKywCCJiIiIiIjIAoMkIiIiIiIiCwySiIiIiIiILDBIIiIiIiIissAgiYiIiIiIyAKDJCIiIiIiIgsMkoiIiIiIiCwwSCIiIiIiIrLAIImIiIiIiMgCgyQiIiIiIiILDJKIiIiIiIgsMEgiIiIiIiKywCCJiIiIiIjIgkuDpBdffBEajcbqJykpyfR5eXk5pk+fjtDQUPj7+2Py5MnIyclxYYqJiIiIiKitc3lN0hVXXIGsrCzTz/bt202fPfHEE1i7di2WL1+OLVu24Pz585g0aZILU0tERERERG1dB5cnoEMHREVF1Zqu1+uxePFifPHFFxgxYgQAYMmSJUhOTsauXbswYMCAlk4qERERERG1Ay6vSTpx4gRiYmLQpUsXTJ06Fenp6QCAffv2oaqqCiNHjjTNm5SUhPj4eOzcubPO5VVUVKCoqMjqh4iIiIiIyF4uDZL69++PpUuXYt26dXj//feRlpaGIUOGoLi4GNnZ2fDy8kJwcLDVdyIjI5GdnV3nMufNm4egoCDTT1xcXDNvBRERERERtSUubW530003mf6+8sor0b9/fyQkJOCrr76Cj49Po5Y5a9YsPPnkk6b/i4qKGCgREREREZHdXN7czlJwcDAuv/xynDx5ElFRUaisrERhYaHVPDk5OTb7MKl0Oh0CAwOtfoiIiIiIiOzlVkHSpUuXcOrUKURHR6Nv377w9PTEpk2bTJ+npqYiPT0dAwcOdGEqiYiIiIioLXNpc7unn34a48aNQ0JCAs6fP48XXngBHh4euOOOOxAUFIT7778fTz75JEJCQhAYGIjHHnsMAwcO5Mh2RERERNRqGQzAtm1AVhYQHQ0MGQJ4eLg6VWTJpUHSuXPncMcdd6CgoADh4eEYPHgwdu3ahfDwcADAO++8A61Wi8mTJ6OiogKjRo3Ce++958okExERERE12qpVwIwZwLlz5mmxscCCBQBfB+o+NIqiKK5ORHMqKipCUFAQ9Ho9+ycRERERkcusWgVMmQLULH1rNPJ7xQoGSs3N3tjArfokERERERG1RQaD1CDZqp5Qp82cKfOR6zFIIiIiIiJqZtu2WTexq0lRgIwMmY9cj0ESEREREVEzy8py7nzUvBgkERERERE1s+ho585HzYtBEhERERFRMxsyREaxUwdpqEmjAeLiZD5yPQZJRERERETNzMNDhvkGagdK6v/z5/N9Se6CQRIRERERUQuYNEmG+e7UyXp6bCyH/3Y3Ln2ZLBERERFRezJpEjB+vIxil5UlfZCGDGENkrthkERERERE1II8PIBhw1ydCqoPm9sRERERERFZYJBERERERERkgUESERERERGRBQZJREREREREFhgkERERERERWWhUkPTZZ59h0KBBiImJwdmzZwEA8+fPx9dff+3UxBEREREREbU0h4Ok999/H08++STGjBmDwsJCGAwGAEBwcDDmz5/v7PQRERERERG1KIeDpH/961/46KOP8Pe//x0eFm+96tevHw4dOuTUxBEREREREbU0h4OktLQ0XH311bWm63Q6lJSUOCVRREREREREruJwkNS5c2ccOHCg1vR169YhOTnZGWkiIiIiIiJymQ6OfuHJJ5/E9OnTUV5eDkVR8Msvv2DZsmWYN28e/u///q850khERERERNRiHA6SHnjgAfj4+OAf//gHSktLceeddyImJgYLFizA7bff3hxpJCIiIiIiajEaRVGUxn65tLQUly5dQkREhDPT5FRFRUUICgqCXq9HYGCgq5NDREREREQuYm9s4HBNkiVfX1/4+vo2ZRFERERERERuxeEgqXPnztBoNHV+fvr06SYliIiIiIiIyJUcDpJmzpxp9X9VVRX279+PdevW4a9//auz0kVEREREROQSDgdJM2bMsDn93//+N/bu3dvkBBEREREREbmSw+9JqstNN92ElStXOmtxRERE1EYYDMDmzcCyZfLbYHB1ioiI6tekgRssrVixAiEhIc5aHBEREbUBq1YBM2YA586Zp8XGAgsWAJMmuS5dRET1cThIuvrqq60GblAUBdnZ2cjLy8N7773n1MQRERFR67VqFTBlClDzZSOZmTJ9xQoGSkTknhwOkiZMmGD1v1arRXh4OIYNG4akpCRnpYuIiIhaMYNBapBsvY1RUQCNBpg5Exg/HvDwaPHkERHVq0kvk20N+DJZIiKilrd5MzB8eMPz/fQTMGxYc6eGWorBYEBVVZWrk0HtmKenJzzqefLi1JfJFhUV2Z0wBiJERESUleXc+ci9qd0vCgsLXZ0UIgQHByMqKqred7s2xK4gKTg4uMGVKIoCjUYDA4esISIiaveio507H7k3NUCKiIiAr69vkwqnRI2lKApKS0uRm5sLAIhuwgXGriDpp59+avQKiIiIqP0ZMkRGscvMtN0vSaORz4cMafm0kXMZDAZTgBQaGurq5FA75+PjAwDIzc1FREREvU3v6mNXkDR06NBGLZyIiIjaJw8PGeZ7yhQJiCwDJbWSYf58DtrQFqh9kHx9fV2cEiKh5sWqqqrmDZJsKS0tRXp6OiorK62mX3nllY1dJBEREbUhkybJMN+23pM0fz6H/25r2MSO3IUz8qLW0S/k5eVh7NixCAgIwBVXXIGrr77a6qexXnvtNWg0GsycOdM0rby8HNOnT0doaCj8/f0xefJk5OTkNHodRERE1LImTQLOnJFR7L74Qn6npTFAIiL35nCQNHPmTBQWFmL37t3w8fHBunXr8Mknn6Bbt2745ptvGpWIPXv24MMPP6xVC/XEE09g7dq1WL58ObZs2YLz589jEq+qRERErYqHhwzzfccd8ptN7Ijso9FosGbNmmZdR2JiIubPn9+s62iNHA6SfvzxR7z99tvo168ftFotEhIScNddd+GNN97AvHnzHE7ApUuXMHXqVHz00Ufo2LGjabper8fixYvx9ttvY8SIEejbty+WLFmCn3/+Gbt27XJ4PUREREREtuzcuRMeHh64+eabHf4ug4y2yeEgqaSkBBEREQCAjh07Ii8vDwDQq1cv/Prrrw4nYPr06bj55psxcuRIq+n79u1DVVWV1fSkpCTEx8dj586ddS6voqICRUVFVj9ERERE5P4MBnkR8bJl8rul3iyzePFiPPbYY9i6dSvOnz/fMislt+ZwkNS9e3ekpqYCAHr37o0PP/wQmZmZ+OCDDxwei/zLL7/Er7/+arMGKjs7G15eXggODraaHhkZiezs7DqXOW/ePAQFBZl+4uLiHEoTEREREbW8VauAxERg+HDgzjvld2KiTG9Oly5dwn//+188/PDDuPnmm7F06dJa86xduxbXXHMNvL29ERYWhokTJwIA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",
      "text/plain": [
       "<Figure size 1000x500 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "# 开始训练\n",
    "\n",
    "def train(X_train, y_train, X_val, y_val):\n",
    "    \"\"\"\n",
    "    使用 RandomForestRegressor 训练模型并评估性能。\n",
    "    \n",
    "    参数:\n",
    "    X_train, y_train -- 训练集特征和目标变量\n",
    "    X_val, y_val -- 验证集特征和目标变量\n",
    "    n_estimators -- 树的数量\n",
    "    max_features -- 寻找最佳分割时要考虑的特征数量\n",
    "    max_depth -- 最大树深\n",
    "    min_samples_split -- 内部节点再划分所需最小样本数\n",
    "    min_samples_leaf -- 叶节点最少样本数\n",
    "    bootstrap -- 是否采用bootstrap采样\n",
    "    \n",
    "    返回:\n",
    "    model -- 训练好的模型\n",
    "    \"\"\"\n",
    "    # 创建随机森林回归器实例\n",
    "    model = RandomForestRegressor(n_estimators=500, random_state=42, bootstrap=False, max_depth=12, \n",
    "                                  max_features='sqrt', min_samples_leaf=2, min_samples_split=2)\n",
    "\n",
    "    # 训练模型\n",
    "    model.fit(X_train, y_train)\n",
    "    \n",
    "    # 预测验证集\n",
    "    y_pred = model.predict(X_val)\n",
    "    \n",
    "    # 计算并打印性能指标-均方对数误差\n",
    "    msle = mean_squared_log_error(y_val, y_pred)\n",
    "    print(f'验证集的均方对数误差（MSLE）: {msle:.2f}')\n",
    "\n",
    "    # 计算分数\n",
    "    Score = 1/(1+msle)\n",
    "    print('均方对数误差分值：',Score)\n",
    "\n",
    "    # 绘制预测值和真实值的对比图\n",
    "    plt.figure(figsize=(10,5))\n",
    "    plt.scatter(range(len(y_val)), y_val, color='blue', label='Actual values')\n",
    "    plt.scatter(range(len(y_pred)), y_pred, color='red', label='Predicted values', alpha=0.5)\n",
    "    plt.title('Comparison of Actual and Predicted Values')\n",
    "    plt.xlabel('Sample index')\n",
    "    plt.ylabel('Target value')\n",
    "    plt.legend()\n",
    "    plt.show()\n",
    "    # 此段代码使用scatter图将预测值和实际值对比显示，蓝色点表示真实值，红色点表示预测值。\n",
    " \n",
    "    # 返回训练好的模型\n",
    "    return model\n",
    "\n",
    "# 然后使用训练集数据(X_train, y_train) 和验证集数据(X_val, y_val)调用训练函数\n",
    "model = train(X_train, y_train, X_val, y_val)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "6bfc974a-437a-4313-b492-336e031be695",
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.12.1"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
